package ru.gerunn.silent.client;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

import ru.gerunn.silent.common.RW;
import ru.gerunn.silent.listener.SilentListener;

public class Client extends Thread {

	private int port;
	private SSLSocket socket;
	private RW clientServerRW;
	private RW serverClientRW;
	private HashMap<String, ArrayList<SilentListener>> listeners;

	public Client() throws UnknownHostException, IOException {
		this.port = 8883;
		this.initialize();
	}

	public Client(int port) throws UnknownHostException, IOException {
		this.port = port;
		this.initialize();
	}

	private void initialize() throws UnknownHostException, IOException {
		this.listeners = new HashMap<String, ArrayList<SilentListener>>();
		SSLSocketFactory socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
		this.socket = (SSLSocket) socketFactory.createSocket("localhost", this.port);
		this.socket.startHandshake();
	}

	public void run() {
		try {
			this.clientServerRW.start();
		} catch (RuntimeException e) {
			for (SilentListener listener : this.getEventListeners("NoClientServerRW")) {
				listener.doEvent();
			}
		}

		try {
			this.serverClientRW.start();
		} catch (RuntimeException e) {
			for (SilentListener listener : this.getEventListeners("NoServerClientRW")) {
				listener.doEvent();
			}
		}
	}

	public int getPort() {
		return port;
	}

	public SSLSocket getSocket() {
		return socket;
	}

	public void setClientServerRW(RW clientServerRW) {
		this.clientServerRW = clientServerRW;
	}

	public void setServerClientRW(RW serverClientRW) {
		this.serverClientRW = serverClientRW;
	}

	public void addEventListener(String event, SilentListener listener) {
		if (this.listeners.get(event) == null) {
			this.listeners.put(event, new ArrayList<SilentListener>());
		}

		this.listeners.get(event).add(listener);
	}

	private ArrayList<SilentListener> getEventListeners(String event) {
		ArrayList<SilentListener> listeners;
		if ((listeners = this.listeners.get(event)) == null) {
			return new ArrayList<SilentListener>();
		} else {
			return listeners;
		}
	}

}
